package com.ozo.easy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ozo.easy.common.model.*;
import com.ozo.easy.common.util.SortUtil;
import com.ozo.easy.common.exception.ServiceException;
import com.ozo.easy.exception.ServiceExceptionEnum;
import com.ozo.easy.pojo.vo.SysDeptDetailVO;
import com.ozo.easy.entity.SysDept;
import com.ozo.easy.mapper.SysDeptMapper;
import com.ozo.easy.pojo.dto.SysDeptSaveDTO;
import com.ozo.easy.pojo.dto.SysDeptQueryDTO;
import com.ozo.easy.pojo.vo.SysDeptVO;
import com.ozo.easy.service.ISysDeptService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 部门 服务实现类
 *
 * @author ozo
 * @version 1.0
 * @date 2025-01-26 16:37:36
 */
@RequiredArgsConstructor
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(SysDeptSaveDTO saveDTO) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDept::getDeptName, saveDTO.getDeptName())
                .eq(SysDept::getParentId, saveDTO.getParentId());
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ServiceException(ServiceExceptionEnum.DEPT_NAME_EXISTS);
        }

        SysDept sysDept = BeanUtil.copyProperties(saveDTO, SysDept.class);
        baseMapper.insert(sysDept);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void remove(BaseBatchDTO<Long> batchDTO) {
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysDept::getParentId, batchDTO.getIdList());
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ServiceException(ServiceExceptionEnum.DEPT_HAS_CHILDREN_NOT_DELETE);
        }

        baseMapper.deleteBatchIds(batchDTO.getIdList());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SysDeptSaveDTO saveDTO) {
        if (saveDTO.getId().equals(saveDTO.getParentId())) {
            throw new ServiceException(ServiceExceptionEnum.PARENT_NOT_ONESELF);
        }
        LambdaQueryWrapper<SysDept> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDept::getDeptName, saveDTO.getDeptName())
                .eq(SysDept::getParentId, saveDTO.getParentId())
                .ne(SysDept::getId, saveDTO.getId());
        Long count = baseMapper.selectCount(queryWrapper);
        if (count > 0) {
            throw new ServiceException(ServiceExceptionEnum.DEPT_NAME_EXISTS);
        }

        SysDept sysDept = BeanUtil.copyProperties(saveDTO, SysDept.class);
        baseMapper.updateById(sysDept);
    }

    @Override
    public List<SysDeptVO> list(SysDeptQueryDTO queryDTO) {
        QueryWrapper<SysDept> queryWrapper = new QueryWrapper<>();
        // 排序
        String order = queryDTO.getOrder();
        if (StrUtil.isBlank(order)) {
            queryWrapper.lambda().orderByDesc(SysDept::getId);
        } else {
            SortUtil.setSortCondition(queryWrapper, queryDTO.getProp(), order);
        }
        // 条件
        queryWrapper.lambda()
                .like(StrUtil.isNotBlank(queryDTO.getDeptName()), SysDept::getDeptName, queryDTO.getDeptName());
        List<SysDept> list = baseMapper.selectList(queryWrapper);

        List<SysDeptVO> recordVOList = BeanUtil.copyToList(list, SysDeptVO.class);

        for (SysDeptVO sysDeptVO : recordVOList) {
            List<SysDeptVO> children = recordVOList.stream().filter(e -> sysDeptVO.getId().equals(e.getParentId())).collect(Collectors.toList());
            sysDeptVO.setChildren(children);
        }

        return recordVOList.stream().filter(e -> e.getParentId() == null).collect(Collectors.toList());
    }

    @Override
    public SysDeptDetailVO detail(Long id) {
        SysDept sysDept = baseMapper.selectById(id);
        if (Objects.isNull(sysDept)) {
            throw new ServiceException(ServiceExceptionEnum.DATA_NOT_EXISTS);
        }

        SysDeptDetailVO sysDeptDetailVO = BeanUtil.copyProperties(sysDept, SysDeptDetailVO.class);
        Long parentId = sysDept.getParentId();
        if (parentId != null) {
            SysDept parent = baseMapper.selectById(parentId);
            sysDeptDetailVO.setParentName(parent != null ? parent.getDeptName() : "");
        }
        return sysDeptDetailVO;
    }

    @Override
    public void enable(Long id) {
        SysDept sysDept = baseMapper.selectById(id);
        if (Objects.isNull(sysDept)) {
            throw new ServiceException(ServiceExceptionEnum.DATA_NOT_EXISTS);
        }
        sysDept.setEnableFlag(!sysDept.getEnableFlag());
        baseMapper.updateById(sysDept);
    }

}
